﻿using System;
/* ========================================================
 *	Stamps for Africa - Manage Stamps Controller
 */
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using ImageHandler;
using Stamp_For_Africa_Version_2.Models;
using Stamp_For_Africa_Version_2.Repositories;
using Stamp_For_Africa_Version_2.ViewModels;

namespace Stamp_For_Africa_Version_2.Controllers
{
	public class ManageStampsController : Controller
	{
		readonly StampRepository _stampRepository = new StampRepository();
		readonly StampFeatureRepository _stampFeatureRepository = new StampFeatureRepository();
		readonly ArtistRepository _artistRepository = new ArtistRepository();
		readonly ColourRepository _colourRepository = new ColourRepository();
		readonly CurrencyRepository _currencyRepository = new CurrencyRepository();
		readonly UploaderRepository _uploaderRepository = new UploaderRepository();
		readonly CountryRepository _countryRepository = new CountryRepository();
		readonly CategoryRepository _categoryRepository = new CategoryRepository();
		readonly CatalogueRepository _catalogueRepository = new CatalogueRepository();
    readonly TypeRepository _typeRepository = new TypeRepository();

		#region HTTP - GET Methods

		private void BuildViewBagItems()
		{
			List<SelectListItem> countryItems = _countryRepository.FindAllCountries().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.Name }).ToList();
			List<SelectListItem> currencyItems = _currencyRepository.FindAllCurrencies().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.DisplayName }).ToList();
			List<SelectListItem> artistItems = _artistRepository.FindAllArtists().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.DisplayName }).ToList();
      List<SelectListItem> issueTypeList = _typeRepository.FindAllTypes().Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.DisplayName }).ToList();
		 	
      List<SelectListItem> categoryItems =
				_categoryRepository.FindAllCategories().Select(
					c => new SelectListItem { Value = c.Id.ToString(), Text = c.DisplayName }).ToList();

			List<SelectListItem> issueType = new List<SelectListItem>();
			SelectListItem regularIssue = new SelectListItem
			{
				Text = "Regular (Definitive) Issue",
				Value = "0"
			};
			SelectListItem provisionalIssue = new SelectListItem
			{
				Text = "Provisional Issue",
				Value = "1"
			};
			SelectListItem commemorativeIssue = new SelectListItem
			{
				Text = "Commemorative Issue",
				Value = "2"
			};
			issueType.Add(regularIssue);
			issueType.Add(provisionalIssue);
			issueType.Add(commemorativeIssue);

			List<SelectListItem> firstIssueDates = new List<SelectListItem>();
			List<String> dates = _stampRepository.GetAllYears();
			foreach (var date in dates)
			{
				SelectListItem item = new SelectListItem
				{
					Text = date,
					Value = date
				};
				firstIssueDates.Add(item);
			}

			ViewBag.CountryList = countryItems;
			ViewBag.CurrencyList = currencyItems;
			ViewBag.ArtistList = artistItems;
			ViewBag.CategoryList = categoryItems;
			ViewBag.IssueTypeList = issueType;
			ViewBag.FirstIssueList = firstIssueDates;
      ViewBag.StampTypeList = issueTypeList;
		}
		private Guid GetUserId()
		{
			MembershipUser user = Membership.GetUser();
			Guid userId = Guid.Empty;
			if (user != null)
				userId = (Guid)user.ProviderUserKey;

			return userId;
		}
		//
		// GET: /Stamps/

		public ActionResult Index(int? id)
		{
			StampIndexFormViewModel formViewModel = null;
			if (TempData.ContainsKey("FormFilters"))
			{
				var pageIndex = id ?? 0;
				formViewModel = (StampIndexFormViewModel)TempData["FormFilters"];

				formViewModel.StampPage = _stampRepository.SelectRange(pageIndex, 10, GetUserId());
				TempData["FormFilters"] = formViewModel;

			}
			else
			{
				var pageIndex = id ?? 0;
				formViewModel = new StampIndexFormViewModel();
				//formViewModel.StampList = _stampRepository.FindAllStamps().ToList();
				//formViewModel.StampPage = _stampRepository.SelectRange(pageIndex, 4);

				formViewModel.PageNumber = 0;
				formViewModel.PageCount = 0;
				formViewModel.MaxResultsPerPage = 10;
			}

			BuildViewBagItems();

			return View("Index", formViewModel);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Index(int? id, FormCollection formValues)
		{
			var formViewModel = new StampIndexFormViewModel();

			string selectedCountryId = formValues["SelectedCountryId"];
			string selectedCurrencyId = formValues["SelectedCurrencyId"];
			string selectedArtistId = formValues["SelectedArtistId"];
			string selectedCategoryId = formValues["SelectedCategoryId"];
			string selectedIssueTypeId = formValues["SelectedIssueTypeId"];
			string selectedFirstYear = formValues["FirstIssue"];


			//formViewModel.StampList = _stampRepository.FindAllStamps(selectedCountryId, selectedArtistId, selectedCurrencyId, selectedCategoryId);
			var pageIndex = id ?? 0;
      formViewModel.StampPage = _stampRepository.SelectRange(pageIndex, 4, selectedCountryId, selectedCategoryId, selectedFirstYear, GetUserId(), selectedIssueTypeId, selectedArtistId);
			formViewModel.ContainsFilters = true;
			formViewModel.SelectedCountryId = selectedCountryId;
			formViewModel.SelectedArtistId = selectedArtistId;
			formViewModel.SelectedCurrencyId = selectedCurrencyId;
			formViewModel.SelectedCategoryId = selectedCategoryId;
			formViewModel.SelectedIssueTypeId = selectedIssueTypeId;
			formViewModel.FirstIssue = selectedFirstYear;

			BuildViewBagItems();

			TempData.Clear();
			TempData.Add("FormFilters", formViewModel);

			return View("Index", formViewModel);
		}


		//
		// GET: /Stamp/Details/Id

		public ActionResult Details(Guid id)
		{

			Stamp stamp = _stampRepository.GetStamp(id, Guid.Empty);

			if (stamp == null)
				return View("NotFound");
			else
				return View("Details", stamp);
		}

		//
		// GET: /Stamps/Create
		[Authorize]
		public ActionResult Create()
		{

			Stamp stamp = new Stamp()
			{
				ArtistId = _artistRepository.GetArtist(new Guid("00000000-0000-0000-0000-000000000000")).Id,
				PrimaryColorId = _colourRepository.GetColour(new Guid("00000000-0000-0000-0000-000000000000")).Id,
				CurrencyId = _currencyRepository.GetCurrency(new Guid("00000000-0000-0000-0000-000000000000")).Id,
				UploaderId = _uploaderRepository.GetUploader(new Guid("00000000-0000-0000-0000-000000000000")).Id,
				CountryId = _countryRepository.GetCountry(new Guid("00000000-0000-0000-0000-000000000000")).Id,
				NonRootedUploadedFileName = "/Images/SelectStamp.jpg",
				NonRootedUploadedControlBlockFileName = "/Images/SelectStamp.jpg"
			};

			ViewData["userCountryId"] = new SelectList(_countryRepository.FindAllCountries().ToList(), "Id", "Name", stamp.CountryId);
			ViewData["userArtistId"] = new SelectList(_artistRepository.FindAllArtists().ToList(), "Id", "Name", stamp.ArtistId);
			ViewData["userColourId"] = new SelectList(_colourRepository.FindAllColours().ToList(), "Id", "Colour1",
																								stamp.PrimaryColorId);
			ViewData["userUploaderId"] = new SelectList(_uploaderRepository.FindAllUploaders().ToList(), "Id", "Name", stamp.UploaderId);
			ViewData["userCurrencyId"] = new SelectList(_currencyRepository.FindAllCurrencies().ToList(), "Id", "DisplayName", stamp.CurrencyId);

			return View(stamp);
		}

		//
		// GET: /Stamps/Edit/2
		[Authorize]
		public ActionResult Edit(Guid id)
		{

			Stamp stamp = _stampRepository.GetStamp(id, Guid.Empty);

			return View(stamp);
		}


		//
		// GET: /Artists/Delete/xxx
		[Authorize]
		public ActionResult Delete(Guid id)
		{

			Stamp stamp = _stampRepository.GetStamp(id, Guid.Empty);

			if (stamp == null)
				return View("NotFound");
			else
				return View(stamp);
		}

		#endregion

		#region HTTP - POST Methods

		//
		// POST: /Artists/Create
		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Create(Stamp stamp)
		{
			if (ModelState.IsValid)
			{

				try
				{
					stamp.Id = Guid.NewGuid();

					ImageMatch imageMatch = new ImageMatch();
					imageMatch.LoadGivenImageFromImageFile(stamp.UploadedFileName);

					//Save temp image features
					String featureFile = stamp.UploadedFileName + ".bin";
					FileImagePersistence.SaveImageFeatures(stamp.UploadedFileName, featureFile);
					Byte[] fileBytes = FileImagePersistence.ReadFileBytes(stamp.UploadedFileName);
					Byte[] featureBytes = FileImagePersistence.ReadFileBytes(featureFile);
					FileImagePersistence.DeleteFile(featureFile);


					

					if (!String.IsNullOrEmpty(stamp.UploadedControlBlockFileName))
					{
						Byte[] controlblockBytes = FileImagePersistence.ReadFileBytes(stamp.UploadedControlBlockFileName);
						stamp.ControlBlockImage = controlblockBytes;
					}
				



					stamp.Image = fileBytes;

					StampFeature feature = new StampFeature();
					feature.Id = Guid.NewGuid();
					feature.Features = featureBytes;
					_stampFeatureRepository.Add(feature);
					_stampFeatureRepository.Save();

					stamp.FeatureId = feature.Id;

					_stampRepository.Add(stamp);
					_stampRepository.Save();

					CatalogueRepository catalogueRepository = new CatalogueRepository();

					catalogueRepository.AddStampToCatalog(stamp.CatalogueId, stamp.Id, stamp.CatalogueNumber);

					return RedirectToAction("Details", new { id = stamp.Id });
				}
				catch
				{
					ModelState.AddRuleViolations(stamp.GetRuleViolations());
				}
			}

			return View(stamp);
		}

		//
		// POST: /Artists/Edit/xxx
		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Edit(Guid id, FormCollection formValues)
		{
			Stamp stamp = _stampRepository.GetStamp(id, Guid.Empty);

			String controlBlockFileName = formValues["UploadedControlBlockFileName"];

			if (!String.IsNullOrEmpty(controlBlockFileName))
			{
				Byte[] controlblockBytes = FileImagePersistence.ReadFileBytes(controlBlockFileName);
				stamp.ControlBlockImage = controlblockBytes;
			}

			try
			{

				UpdateModel(stamp);
				_stampRepository.Save();

				return RedirectToAction("Details", new { id = stamp.Id });
			}
			catch
			{
				ModelState.AddRuleViolations(stamp.GetRuleViolations());

				return View(stamp);
			}


		}

		//
		// HTTP POST: /Artists/Delete/xxx
		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Delete(Guid id, string confirmButton)
		{

			Stamp stamp = _stampRepository.GetStamp(id, Guid.Empty);

			if (stamp == null)
				return View("NotFound");

			_stampRepository.Delete(stamp);
			_stampRepository.Save();

			return View("Deleted");
		}

		#endregion


		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult FileUpload(StampImageUploadModel uploadedFileMeta)
		{

			try
			{
				var fileName = this.Server.MapPath("~/uploads/" + System.IO.Path.GetFileName(uploadedFileMeta.fileData.FileName));
				var nonRootedPath = "/uploads/" + System.IO.Path.GetFileName(uploadedFileMeta.fileData.FileName);
				uploadedFileMeta.fileData.SaveAs(fileName);
				return Json(new { Status = "OK", returnFile = fileName, serverPath = nonRootedPath });
			}
			catch (Exception ex)
			{
				return Json(new { Status = "Failed" });
			}

		}


		public ActionResult ShowStamp(Guid id)
		{
			StampRepository repository = new StampRepository();
			Stamp stamp = repository.GetStamp(id, Guid.Empty);

			return File(stamp.Image.ToArray(), "image/jpg");
		}

		public ActionResult AssignStampToCatalogue(Guid stampId)
		{
			ManageStampViewModel manageStampViewModel = new ManageStampViewModel();
			manageStampViewModel.Stamp = _stampRepository.GetStamp(stampId, Guid.Empty);
			manageStampViewModel.StampId = stampId;

			manageStampViewModel.AssignedCatalogues = _catalogueRepository.GetCatalogueEntriesForStamp(stampId);
			return View(manageStampViewModel);
		}

		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult AssignStampToCatalogue(ManageStampViewModel manageStampViewModel)
		{
			//ManageStampViewModel manageStampViewModel = new ManageStampViewModel();
			//manageStampViewModel.Stamp = _stampRepository.GetStamp(stampId, Guid.Empty);
			_catalogueRepository.AddStampToCatalog(manageStampViewModel.SelectedCatalogueId, manageStampViewModel.StampId, manageStampViewModel.CatalogueNumber);
			return RedirectToAction("Index");
		}

		public ActionResult RemoveCatalogueAssignment(Guid catalogueEntryId, Guid stampId)
		{
			_catalogueRepository.RemoveCatalogueEntry(catalogueEntryId);
			return RedirectToAction("AssignStampToCatalogue", new {stampId});
		}

		public ActionResult ManageStampVariants(Guid stampId)
		{
			ManageStampViewModel manageStampViewModel = new ManageStampViewModel();
			manageStampViewModel.Stamp = _stampRepository.GetStamp(stampId, Guid.Empty);
			manageStampViewModel.StampVariants = _stampRepository.GetStampVariations(stampId);
			manageStampViewModel.NewVariation = new Variation();
			return View(manageStampViewModel);
		}

    public ActionResult LinkStampToStamp(Guid stampId, LinkStampViewModel linkStampViewModel)
    {

      if (TempData["linkStampViewModel"] != null)
        linkStampViewModel = (LinkStampViewModel) TempData["linkStampViewModel"];

      if (linkStampViewModel == null)
      {
        linkStampViewModel = new LinkStampViewModel();
        linkStampViewModel.ParentStamp = _stampRepository.GetStamp(stampId, Guid.Empty);
        linkStampViewModel.StampLink = new StampLink();
        linkStampViewModel.StampIndexFormViewModel = new StampIndexFormViewModel();
      }
      else
      {
        
      }
      BuildViewBagItems();
      return View(linkStampViewModel);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult LinkStampToStamp(LinkStampViewModel linkStampViewModel, FormCollection formCollection)
    {
      String sSelectedChildId = formCollection["SelectedChildId"];
      String sLinkType = formCollection["LinkType"];
      String sParentStampId = formCollection["ParentStamp.Id"];

      _stampRepository.LinkStamptoStamp(Guid.Parse(sParentStampId), Guid.Parse(sSelectedChildId), (LinkType)Enum.Parse(typeof(LinkType),sLinkType));        
     
      return RedirectToAction("Details", new {id=Guid.Parse(sParentStampId)}); 
    }


    public ActionResult LinkSearch(FormCollection formCollection)
    {
      String sLinkType = formCollection["LinkType"];
      String sPageId = formCollection["PageId"];
      String sParentStampId = formCollection["ParentStamp.Id"];
      String sStampLinkId = formCollection["StampLink.Id"];
      int ? id = int.Parse(sPageId);

      StampIndexFormViewModel formViewModel = null;
      LinkStampViewModel linkStampViewModel = new LinkStampViewModel();
      linkStampViewModel.LinkType = (LinkType)Enum.Parse( typeof(LinkType) , sLinkType);
      linkStampViewModel.PageId = (int)id;
      linkStampViewModel.ParentStamp = _stampRepository.GetStamp(Guid.Parse(sParentStampId), Guid.Empty);
      
      

      if (TempData.ContainsKey("FormFilters"))
      {
        var pageIndex = id ?? 0;
        formViewModel = (StampIndexFormViewModel)TempData["FormFilters"];

        formViewModel.StampPage = _stampRepository.SelectRange(pageIndex, 10, GetUserId());
        TempData["FormFilters"] = formViewModel;

      }
      else
      {
        var pageIndex = id ?? 0;
        formViewModel = new StampIndexFormViewModel();

        formViewModel.PageNumber = 0;
        formViewModel.PageCount = 0;
        formViewModel.MaxResultsPerPage = 10;
      }

      BuildViewBagItems();
      linkStampViewModel.StampIndexFormViewModel = formViewModel;
      TempData["linkStampViewModel"] = linkStampViewModel;
      return RedirectToAction("LinkStampToStamp", new { stampId = Guid.Parse(sParentStampId), linkStampViewModel = linkStampViewModel} );
    }

		public ActionResult DeleteStampVariationLink(Guid parentId, Guid childId)
		{
			_stampRepository.RemoveStampLink(parentId, childId);
			return RedirectToAction("Details", new {id = parentId});
		}
	}
}
